#!/bin/bash
# zimbrarestore.sh
# This script running zimbrarestore on a ZCS server. It also makes sure
# the script's dependencies are present.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

show_help ()
{
echo "Usage: 
     zimbrarestore -r mail1,mail2,...,mailn nome_da_sessao	
			Restore content from accounts specified by command line.
			If yout dont provide the name session will be run a full restore: All Backup found, from the oldest to the newer.
     zimbrarestore -restoreAccount mail1,mail2,...,mailn
			Restore accounts removed from the older backup to the newer.
     zimbrarestore -restoreAccount mail1,mail2,...,mailn --LDAPOnly nome_da_sessao
			Restore only the user profile, including password.
			TIP: Could be necesery update the server cache to apply restored attributes.
			      zmprov fc account nome_da_conta
     zimbrarestore -ldap 	
			Execute full restore, all accounts.
     zimbrarestore -ldap mail1,mail2,...,mailn
			Execute restore full for specific accounts.
     zimbrarestore --restoreAllAccounts 
			Restore all accounts 

     zimbrarestore --restoreOnAccount <orig_account> <dst_account>
                        Restore backup on another specified account
     zimbrarestore --restoreDistributionList
			Restore all distribution lists from last backup
     zimbrarestore --restoreAlias
			Restore all alias from last backup

"
exit 0 
}

###### MAIN ############
#Specify Domain for restore all accounts.
DOMAIN='dc=domain,dc=com,dc=br'

# Here the code loads the config file
source /etc/zimbrabackup/zimbrabackup.conf

#
if ! [ -z "$BACKUPUSER" ]; then
	if [ "$(id -u)" != "$(id -u $BACKUPUSER)" ]; then
		echo "You need to be $BACKUPUSER to run this script"
		exit 0
	fi
else
	echo "You need to define the variable BACKUPUSER"
	exit 0
fi

if ! [ -z "$WORKDIR" ]; then
        if ! [ -d "$WORKDIR" ]; then
                echo "The directory $WORKDIR doesn't exist"
                exit 0
        fi
else
        echo "You need to define the variable WORKDIR"
        exit 0
fi

if [ -z "$ADMINUSER" ]; then
        echo "You need to define the variable ADMINUSER"
        exit 0
fi

if [ -z "$ADMINPASS" ]; then
        echo "You need to define the variable ADMINPASS"
        exit 0
fi

if [ -z "$LDAPMASTERSERVER" ]; then
        echo "You need to define the variable LDAPMASTERSERVER"
        exit 0
fi

if [ -z "$LDAPZIMBRADN" ]; then
        echo "You need to define the variable LDAPZIMBRADN"
        exit 0
fi

if [ -z "$LDAPZIMBRAPASS" ]; then
        echo "You need to define the variable LDAPZIMBRAPASS"
        exit 0
fi

if [ -z "$LOGFILE" ]; then
        echo "You need to define the variable LOGFILE"
        exit 0
fi

# Function to notify completes restore trough e-mail
notify_email()
{
	
	TIPO=$1;
	session=$2;
	du -h $WORKDIR/$session/* > /tmp/list-$session ;
	total=$(du -h $WORKDIR/$session | awk {'print $1'});
	(echo "Subject: Restore $TIPO completed on $(date)";echo "Restore $TIPO completed on $(date)";echo -e "\r\nTotal: $total ";echo "Summary of files:"; cat /tmp/list-$session) | /opt/zimbra/postfix/sbin/sendmail $EMAIL_NOTIFY
}

restore_accounts ()
{

	BKPSACCOUNT=$(mktemp)
	K=1
	
	while true; do

	        MAIL=$(echo $1, | cut -d, -f$K)

	        if [ -z $MAIL ]; then
	                break
	        fi

	        grep $MAIL $WORKDIR/sessions.txt | grep -v ^WARN: > $BKPSACCOUNT

	        if ! [ -s $BKPSACCOUNT ]; then
	                echo "$MAIL: No backup found. Impossible to restor"
	                ((K = K+1))
	        else
                	if [ -z $2 ]; then
                		echo "Not implemented."
                		# Restauração completa
				# Complete restoration
                		((K = K+1))
                	else
                        	SESSIONACCOUNT=$(grep $2 $WORKDIR/sessions.txt | tail -1 | awk '{print $2}')

	                        if [ -z $SESSIONACCOUNT ]; then
	                                echo "$MAIL: Session $2 doesn't exist. Impossible to continue."
	                                break
	                        else
	                                ACCOUNTONSESSION=$(grep $MAIL $BKPSACCOUNT | grep $SESSIONACCOUNT)
                                	if [ -z $ACCOUNTONSESSION ]; then
                                        	echo "$MAIL not found in session $SESSIONACCOUNT. Impossible to restore."
                                        	((K = K+1))
                                	else
                                        	MAILHOST=$(grep ^zimbraMailHost $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
	                                        $(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/?fmt=tgz
        	                                $(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Junk.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Junk?fmt=tgz
        	                                $(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Trash.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Trash?fmt=tgz
        	                                ((K = K+1))
        	                                unset MAIL
                                	fi
                        	fi
                	fi
        	fi
	done
	exit 0
}


restore_on_box()
{
		BKPSACCOUNT=$(mktemp)
	        MAIL=$1
		DEST=$2
	        if [ -z $MAIL ]; then
	                break
	        fi

	        if [ -n $DEST ]; then

			grep $MAIL $WORKDIR/sessions.txt | grep -e ^inc- -e ^full- > $BKPSACCOUNT
			if ! [ -s $BKPSACCOUNT ]; then
	               		echo "$MAIL: No backup found. Impossible to restore."
	                	exit 1
	                else
	                	echo "Sessions found $(cat $BKPSACCOUNT | awk -F: '{print $1}')"
				
				for SESSIONACCOUNT in $(cat $BKPSACCOUNT | awk -F: '{print $1}'); do
					echo "Restoring from $SESSIONACCOUNT on $DEST"
					MAILHOST=$(grep ^zimbraMailHost $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')                                  	                                        	
					$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$DEST/?fmt=tgz
					$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Junk.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$DEST/Junk?fmt=tgz
					$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Trash.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$DEST/Trash?fmt=tgz
					echo "$MAIL restored from  $SESSIONACCOUNT on $DEST"
                                done
                                	unset MAIL
                        	fi
                	fi
        	
	
}







restore_LDAP_account_per_domain ()
{
	BKPSACCOUNT=$(mktemp)
	K=1

	while true; do
	
	        MAIL=$(echo $1, | cut -d, -f$K)
	        if [ -z $MAIL ]; then
	                break
	        fi

	        if [ -z $2 ]; then

	                EXISTE=$($(which ldapsearch) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -w $LDAPZIMBRAPASS -b $DOMAIN -LLL "(&(objectclass=zimbraAccount)(zimbraMailDeliveryAddress=$MAIL))" uid)
	                if ! [ -z "$EXISTE" ]; then
	                        echo "Account $MAIL exists. Use zmbkpose -r $MAIL SESSION_name."
	                        ((K = K+1))
	                else
	                        grep $MAIL $WORKDIR/sessions.txt | grep -e ^inc- -e ^full- > $BKPSACCOUNT
	                        if ! [ -s $BKPSACCOUNT ]; then
	                                echo "$MAIL: No backup found. Impossible to restore."
	                                ((K = K+1))
	                        else
	                                echo "Sessions found $(cat $BKPSACCOUNT | awk -F: '{print $1}')"
	                                for SESSIONACCOUNT in $(cat $BKPSACCOUNT | awk -F: '{print $1}'); do
	                                        echo "Restoring from $SESSIONACCOUNT"
                                        	MAILHOST=$(grep ^zimbraMailHost $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
                                        	$(which ldapdelete) -r -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS $(grep ^dn: $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}') 2>/dev/null
                                        	$(which ldapadd) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS -f $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff
                                        	$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/?fmt=tgz
                                        	$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Junk.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Junk?fmt=tgz
                                        	$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Trash.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Trash?fmt=tgz
                                        	echo "$MAIL restored from  $SESSIONACCOUNT"
                                	done
                                	((K = K+1))
                                	unset MAIL
                        	fi
                	fi
        	else
                	SESSIONACCOUNT=$(grep $2 $WORKDIR/sessions.txt | grep $MAIL | tail -1 | awk -F: '{print $1}')
                	if [ -z $SESSIONACCOUNT ]; then
                	        echo "$MAIL: Session $2 doesn't exist or account not present. Impossible to restore."
                	        ((K = K+1))
                	else
                        	USERDN=$(grep ^dn: $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
                        	$(which ldapdelete) -r -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS $USERDN
                        	$(which ldapadd) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS -f $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff
                        	echo "User's profile and configurations restored to $SESSIONACCOUNT"
                        	((K = K+1))
                        	unset MAIL
                	fi
        	fi
	done
	exit 0
}



restore_all_accounts_parallel ()
{
	for BKP in $(grep -e ^full- -e ^inc- $WORKDIR/sessions.txt); do
		STAT=$(ps aux | grep -i curl | grep -v grep| wc -l)
	
		if [ $STAT -lt $MAX_PARALLEL_PROCESS ];then
        		
			SESSIONACCOUNT=$(echo $BKP | awk -F: '{print $1}')
		        MAIL=$(echo $BKP | awk -F: '{print $2}')
       		
	        	USERDN=$(grep ^dn: $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
		        MAILHOST=$(grep ^zimbraMailHost $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
	        	echo "Restoring $MAIL"

		        $(which ldapdelete) -r -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS $USERDN 2>/dev/null
	        	$(which ldapadd) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS -f $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff

		        $(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/?fmt=tgz &	
			$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Junk.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Junk?fmt=tgz &
		        $(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Trash.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Trash?fmt=tgz &

			echo "$MAIL restored"
		else
			until [ $STAT -lt $MAX_PARALLEL_PROCESS ]
	                do
	                        STAT=$(ps aux | grep -i curl | grep -v grep| wc -l)
	                        sleep 5
				#Número máximo de processos atingido ($STAT). Aguardando vaga."
	                done
		
			SESSIONACCOUNT=$(echo $BKP | awk -F: '{print $1}')
	                MAIL=$(echo $BKP | awk -F: '{print $2}')

			USERDN=$(grep ^dn: $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
			MAILHOST=$(grep ^zimbraMailHost $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff | awk '{print $2}')
			echo "Restoring $MAIL"
			
			$(which ldapdelete) -r -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS $USERDN 2>/dev/null
			$(which ldapadd) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS -f $WORKDIR/$SESSIONACCOUNT/$MAIL.ldiff

			$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/?fmt=tgz &
			$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Junk.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Junk?fmt=tgz &
			$(which curl) -k --data-binary @$WORKDIR/$SESSIONACCOUNT/$MAIL.Trash.tgz -u $ADMINUSER:$ADMINPASS https://$MAILHOST:7071/home/$MAIL/Trash?fmt=tgz &
			echo "$MAIL restored"

		fi
	done
	
	exit 0
}


restore_alias()
{
	for BKP in $(grep -e "^alias-"  $WORKDIR/sessions.txt); do
		SESSAOCONTA=$(echo $BKP | awk -F: '{print $1}')
		MAIL=$(echo $BKP | awk -F: '{print $2}')
		$(which ldapadd) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS -f $WORKDIR/$SESSAOCONTA/$MAIL.ldiff	
	done
}


restore_distribution_list()
{
        for BKP in $(grep -e "^distlist-"  $WORKDIR/sessions.txt); do
                SESSAOCONTA=$(echo $BKP | awk -F: '{print $1}')
                MAIL=$(echo $BKP | awk -F: '{print $2}')
                $(which ldapadd) -x -H $LDAPMASTERSERVER -D $LDAPZIMBRADN -c -w $LDAPZIMBRAPASS -f $WORKDIR/$SESSAOCONTA/$MAIL.ldiff
        done
}

# Criticize the parameters passed on the command line

"-r" )
        if [ -z "$2" ]; then
                echo "Incorrect $@ params. Read the --help."
                show_help
	else
		if [ -z "$4" ]; then
			restore_accounts $2 $3
		else
                	echo "Incorrect $@ params. Read the --help."
	                show_help
		fi
	fi
;;
"-restoreAccount" )
        if [ -z "$2" ]; then
                echo "Incorrect $@ params. Read the --help."
                show_help
	else
		if [ -z "$3" ]; then
			restore_LDAP_account $2
		else
			if [ "$3" = "--LDAPOnly" ]; then
				restore_LDAP_account $2 $4
			else
	                	echo "Incorrect $@ params. Read the --help."
		                show_help
			fi
		fi
	fi
	
;;
"--restoreAllAccounts" )
	restore_all_accounts_parallel
;;
"--restoreAlias" )
	restore_alias
;;
"--restoreDistributionList" )
	restore_distribution_list
;;
"--restoreOnAccount" )
	if ! [   -z $2 -o -z $3    ]; then
        	restore_on_box $2 $3
	fi
;;
* )
	echo "Incorrect parameters $@. See help."
	show_help
;;
esac
exit 0